<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\CustHub\Helpers\BcMath;
use App\CustHub\Mapper\ChSendRecordMapper;
use App\CustHub\Mapper\ChSmartPushSchemeMapper;
use App\CustHub\Mapper\ChSmartPushSchemeStatisticsMapper;
use App\CustHub\Mapper\ChSmartPushSchemeSubTaskMapper;
use App\CustHub\Mapper\ChSmartPushSchemeTargetTaskMapper;
use Carbon\Carbon;
use Carbon\CarbonPeriod;
use Hyperf\Di\Annotation\Inject;
use Mine\Abstracts\AbstractService;
use Mine\Exception\NormalStatusException;
use Mine\MineModel;
use function Hyperf\Collection\data_get;

class ChSmartPushSchemeStatisticsService extends AbstractService
{
    public $mapper;

    #[Inject]
    protected ChSmartPushSchemeMapper $schemeMapper;

    #[Inject]
    protected ChSmartPushSchemeSubTaskMapper $smartPushSchemeSubTaskMapper;

    #[Inject]
    protected ChSmartPushSchemeTargetTaskMapper $smartPushSchemeTargetTaskMapper;


    #[Inject]
    protected ChSendRecordMapper $sendRecordMapper;

    public function __construct(ChSmartPushSchemeStatisticsMapper $mapper)
    {
        $this->mapper = $mapper;
    }


    public function getStatsList(array $params): array
    {

        $type = data_get($params,'type',0);

        $schemeInfo = $this->schemeMapper->findById($params['id']);
        if(empty($schemeInfo)){
            throw new NormalStatusException('请选择方案');
        }

        $targetQuery = $this->smartPushSchemeTargetTaskMapper->model::query()
            ->selectRaw('trigger_date,count(user_id) as completed_count')
            ->where('scheme_id',$schemeInfo->id)
            ->where('status',1);

        $endDate = Carbon::now()->toDateString();
        switch ($type){
            case 1:
                $startDate = Carbon::now()->subDays(14)->startOfDay()->toDateString();
                break;
            case 2:
                $startDate = Carbon::now()->subDays(30)->startOfDay()->toDateString();
                break;
            case 3:
                $startDate = $params['start_date'];
                $endDate = $params['end_date'];
                break;
            default:
                $startDate = Carbon::now()->subDays(7)->toDateString();
                break;
        }

        $period = CarbonPeriod::create($startDate,$endDate);

        $targetMap = $targetQuery
            ->whereBetween('trigger_date',[$startDate,$endDate])
            ->groupBy('trigger_date')
            ->pluck('completed_count','trigger_date')
            ->toArray();

        if($schemeInfo->push_type == 2){

            $startTime = Carbon::now()->timestamp(strtotime($startDate))->startOfDay()->timestamp;
            $endTime = Carbon::now()->timestamp(strtotime($endDate))->endOfDay()->timestamp;

            //定时-目标完成的情况
            $completedMap = $this->sendRecordMapper->model::query()
                ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(trigger_time), '%Y-%m-%d') AS date,SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) AS completed_count")
                ->where('task_id',$schemeInfo->id)
                ->where('trigger_time','>=',$startTime)
                ->where('trigger_time','<=',$endTime)
                ->groupBy('date')
                ->pluck('completed_count','date')
                ->toArray();
        }else{
            $completedMap = $this->smartPushSchemeSubTaskMapper->model::query()
                ->selectRaw('day as date,ifnull(sum(contact_count),0) completed_count')
                ->where('scheme_id',$schemeInfo->id)
                ->whereBetween('day',[$startDate,$endDate])
                ->groupBy('day')
                ->pluck('completed_count','date')
                ->toArray();
        }
        $list = [];
        foreach ($period as $date){
            $date = $date->format('Y-m-d');
            $targetCompletedCnt = data_get($targetMap,$date,0);
            $completedCnt = data_get($completedMap,$date,0);
            if($completedCnt == 0){
                $targetCompletedRate = 0;
            }else{
                $targetCompletedRate = BcMath::div($targetCompletedCnt,$completedCnt);
            }

            $list[$date] = [
                '完成率' => $targetCompletedRate.'%',
            ];
        }
        return $list;
    }

    /**
     * 获取详细数据列表
     * @param array $params
     * @return array
     */
    public function getDetailedDataList(array $params): array
    {
        $schemeId = $params['scheme_id'];

        $schemeInfo = $this->schemeMapper->findById($schemeId);
        if(empty($schemeInfo)){
            throw new NormalStatusException('请选择方案');
        }

        $pageSize = $params['page_size'] ?? MineModel::PAGE_SIZE;


        $targetList = $this->smartPushSchemeTargetTaskMapper->model::query()
            ->selectRaw('trigger_date,count(user_id) as completed_count')
            ->where('scheme_id',$schemeInfo->id)
            ->where('status',1)
            ->groupBy('trigger_date')
            ->pluck('completed_count','trigger_date')
            ->toArray();

        if($schemeInfo->push_type == 2){
            //定时-目标完成的情况
            $p = $this->sendRecordMapper->model::query()
                ->selectRaw("DATE_FORMAT(FROM_UNIXTIME(trigger_time), '%Y-%m-%d') AS date,count(to_id) AS contact_count,SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) AS completed_count")
                ->where('task_id',$schemeInfo->id)
                ->groupBy('date')
                ->orderBy('date','desc')
                ->paginate((int)$pageSize);
        }else{
            $p = $this->smartPushSchemeSubTaskMapper->model::query()
                ->selectRaw('day as date,ifnull(sum(contact_count),0) contact_count,ifnull(sum(contact_count),0) completed_count')
                ->where('scheme_id',$schemeInfo->id)
                ->groupBy('day')
                ->orderBy('day','desc')
                ->paginate((int)$pageSize);
        }

        $p->getCollection()->transform(function ($item) use ($targetList){
            //查询目标完成数量
            $item->target_completed_count = data_get($targetList,$item->date,0);
            //查询目标完成率
            if($item->completed_count > 0){
                $item->target_completed_rate = BcMath::div($item->target_completed_count,$item->completed_count);
            }else{
                $item->target_completed_rate = 0;
            }
            return $item;
        });

        return $this->mapper->setPaginate($p);
    }
}